/*
 * @(#)RegistryResponseTypeTransformer.java
 * Date 2013-09-22
 * Version 1.0
 * Author Jim Horner
 * Copyright (c)2012
 */


package us.hornerscorners.lamppost.registry.transformer.xds;

import java.util.List;

import javax.enterprise.context.ApplicationScoped;

import oasis.names.tc.ebxml_regrep.xsd.rs._3.RegistryError;
import oasis.names.tc.ebxml_regrep.xsd.rs._3.RegistryErrorList;
import oasis.names.tc.ebxml_regrep.xsd.rs._3.RegistryResponseType;

import org.apache.commons.lang3.ClassUtils;

import us.hornerscorners.lamppost.exception.ServiceActionError;
import us.hornerscorners.lamppost.exception.ServiceActionException;

import us.hornerscorners.lamppost.registry.constant.ErrorCode;
import us.hornerscorners.lamppost.registry.constant.ErrorSeverityType;
import us.hornerscorners.lamppost.registry.constant.ResponseStatus;

import us.hornerscorners.lamppost.registry.model.RegistryResponse;

import us.hornerscorners.lamppost.transformer.AbstractTransformer;

import static us.hornerscorners.lamppost.exception.SeverityType.Error;
import static us.hornerscorners.lamppost.exception.SeverityType.Warning;


/**
 * Class description
 *
 *
 * @version        v1.0, 2013-09-22
 * @author         Jim Horner
 */
@ApplicationScoped
public class RegistryResponseTypeTransformer
        extends AbstractTransformer<RegistryResponse, RegistryResponseType> {

    /** Field description */
    private final ErrorCode defaultError;

    /**
     * Constructs ...
     *
     *
     * @param defaultError
     */
    public RegistryResponseTypeTransformer(ErrorCode defaultError) {

        super();
        this.defaultError = defaultError;
    }

    /**
     * Method description
     *
     *
     * @param errorLocation
     * @param error
     *
     * @return
     */
    public RegistryError createRegistryError(Class errorLocation,
            ServiceActionError error) {

        return createRegistryError(ClassUtils.getShortClassName(errorLocation), error);
    }

    /**
     * Method description
     *
     *
     * @param errorLocation
     * @param error
     *
     * @return
     */
    private RegistryError createRegistryError(String errorLocation,
            ServiceActionError error) {

        RegistryError result = new RegistryError();

        result.setLocation(errorLocation);
        result.setCodeContext(error.getCodeContext());

        switch (error.getSeverity()) {

            case Warning :
                result.setSeverity(ErrorSeverityType.Warning.getCode());

                break;

            case Error :
                result.setSeverity(ErrorSeverityType.Error.getCode());

                break;
        }

        ErrorCode errorCode = ErrorCode.toErrorCode(error.getErrorCode());

        if (errorCode == null) {
            errorCode = this.defaultError;
        }

        result.setErrorCode(errorCode.getCode());

        return result;
    }

    /**
     * Method description
     *
     *
     * @param exception
     *
     * @return
     */
    public RegistryErrorList createRegistryErrorList(ServiceActionException exception) {

        RegistryErrorList result = new RegistryErrorList();

        List<RegistryError> list = result.getRegistryError();

        for (ServiceActionError error : exception.getErrors()) {

            list.add(createRegistryError(exception.getLocation(), error));
        }

        return result;
    }

    /**
     * Method description
     *
     *
     *
     * @param errorLocation
     * @param error
     * @return
     */
    public RegistryErrorList createRegistryErrorList(Class errorLocation,
            ServiceActionError error) {

        return createRegistryErrorList(new ServiceActionException(errorLocation, error));
    }

    /**
     * Method description
     *
     *
     *
     * @param response
     * @return
     */
    @Override
    public RegistryResponseType transform(RegistryResponse response) {

        RegistryResponseType result = transform(response.getResponseStatus());

        if (response.hasErrors()) {

            result.setRegistryErrorList(createRegistryErrorList(response.getException()));
        }

        return result;
    }

    /**
     * Method description
     *
     *
     * @param responseStatus
     *
     * @return
     */
    public RegistryResponseType transform(ResponseStatus responseStatus) {

        RegistryResponseType result = new RegistryResponseType();

        result.setStatus(responseStatus.getCode());

        return result;
    }

    /**
     * Method description
     *
     *
     * @param responseStatus
     * @param location
     * @param errorCode
     * @param codeContext
     * @param severityType
     *
     * @return
     */
    public RegistryResponseType transform(ResponseStatus responseStatus, Class location,
            ErrorCode errorCode, String codeContext, ErrorSeverityType severityType) {

        RegistryResponseType result = transform(responseStatus);
        RegistryErrorList registryErrorList = new RegistryErrorList();
        RegistryError registryError = new RegistryError();

        registryError.setCodeContext(codeContext);
        registryError.setErrorCode(errorCode.getCode());
        registryError.setLocation(ClassUtils.getShortClassName(location));
        registryError.setSeverity(severityType.getCode());
        registryErrorList.getRegistryError().add(registryError);
        result.setRegistryErrorList(registryErrorList);

        return result;
    }
}
